\chapter{TurboGears}
\section{Primer vistazo}
Luego de elegir el nombre y crear correctamente el proyecto, podemos entrar al
directorio que nos cre'o este comando y ver la lista de archivos que nos
gener'o; explicamos en detalle los m'as importantes.

\begin{description}
    \item [dev.cfg] {\em archivo de configuraci'on} contiene la informaci'on
sobre qu'e base de datos utilizaremos, el puerto en que se van a escuchar las
peticiones del explorador y la configuraci'on del sistema de loggin.
    \item [setup.py] {\em montaje} se utiliza para la configuraci'on del
proyecto en el directorio actual. Generalmente se lo ejecuta antes de empezar a
trabajar en el proyecto..
    \item [start-wwwpayaso.py] {\em webserver} es el servidor web, el cual debe
ser iniciado antes de poder visualizar la p'agina que hemos creado.
    \item [wwwpayaso/model.py] {\em modelo} en este archivo se debe poner todo
lo referido al modelo. Las tablas de la base de datos se encuentran en este
archivo.
    \item [wwwpayaso/templates] {\em vista} este directorio contiene todos las
plantillas XHTML con extenci'on {\em .kid} las cuales son las que se mostrar'an
cuando el usuario solicite una p'agina.
    \item [wwwpayaso/controllers.py] {\em controlador} aqu'i se crean todos los
m'etodos a los cuales la p'agina debe responder. En otras palabras est'an todas
las funciones que necesita el sistema para poder funcionar.
    \item [wwwpayaso/static] {\em images, css, etc} en este directorio se
encuentran todos los datos que son est'aticos, como ser las im'agenes que se
mostrar'an en la web o las hojas de estilos CSS, por ejemplo.
\end{description}

Veamos c'omo se ve la primer p'agina de ejemplo que se genera cuando se crea el
proyecto. Para esto abrimos una consola y tipeamos:

\begin{verbatim}
[manuel] [~/wwwpayaso]$ ./start-wwwpayaso.py
2007-08-15 21:57:25,773 cherrypy.msg INFO CONFIG: Server parameters:
2007-08-15 21:57:25,774 cherrypy.msg INFO CONFIG:   server.environment:
development
2007-08-15 21:57:25,774 cherrypy.msg INFO CONFIG:   server.log_to_screen: True
2007-08-15 21:57:25,775 cherrypy.msg INFO CONFIG:   server.log_file:
2007-08-15 21:57:25,775 cherrypy.msg INFO CONFIG:   server.log_tracebacks: True
2007-08-15 21:57:25,775 cherrypy.msg INFO CONFIG:   server.log_request_headers:
True
2007-08-15 21:57:25,775 cherrypy.msg INFO CONFIG:   server.protocol_version:
HTTP/1.0
2007-08-15 21:57:25,776 cherrypy.msg INFO CONFIG:   server.socket_host:
2007-08-15 21:57:25,776 cherrypy.msg INFO CONFIG:   server.socket_port: 8080
2007-08-15 21:57:25,776 cherrypy.msg INFO CONFIG:   server.socket_file:
2007-08-15 21:57:25,776 cherrypy.msg INFO CONFIG:   server.reverse_dns: False
2007-08-15 21:57:25,777 cherrypy.msg INFO CONFIG:   server.socket_queue_size: 5
2007-08-15 21:57:25,777 cherrypy.msg INFO CONFIG:   server.thread_pool: 10
2007-08-15 21:57:25,942 cherrypy.msg INFO HTTP: Serving HTTP on
http://localhost:8080/
\end{verbatim}

Lo que nos indica en la 'ultima l'inea es que est'a escuchando las
peticiones en la direcci'on {\em http://localhost} en el puerto {\em 8080}.
Para acceder a la p'agina principal vamos a un navegador, en mi caso Mozilla
Firefox
\footnote{http://www.mozilla-europe.org/es/products/firefox/}, y ponemos en la
barra de direcciones {\em http://localhost:8080}; lo cual visulizar'a algo
parecido a la Figura ~\ref{fig:welcome}. Lo que nos indica que el proyecto est'a
funcionando correctamente y el servidor web est'a bien configurado. Si logramos
esto tenemos un buen comienzo, y eso no es poco en estos temas.

\begin{figure}[ht]
\centering
\includegraphics[scale=0.25]{images/fig-01.eps}
\caption{{\small Welcome To TurboGears}}
\label{fig:welcome}
\end{figure}


\section{Modelo, vista y controlador}
\subsection{Introducci'on}
Modelo Vista Controlador (MVC) es un patr'on de arquitectura de software que
separa los datos de una aplicaci'on, la interfaz de usuario, y la l'ogica de
control en tres componentes distintos. El patr'on MVC se ve frecuentemente en
aplicaciones web, donde la vista es la p'agina HTML y el c'odigo que provee de
datos din'amicos a la p'agina, el controlador es el {\em Sistema de Gesti'on de
Base de Datos} y el modelo es el modelo de datos.

\begin{itemize}
    \item Modelo: Esta es la representaci'on espec'ifica de la informaci'on con
la cual el sistema opera. La l'ogica de datos asegura la integridad de estos y
permite derivar nuevos datos; por ejemplo, no permitiendo comprar un n'umero de
unidades negativo, calculando si hoy es el cumplea~nos del usuario o los
totales, impuestos o portes en un carrito de la compra.
    \item Vista: Este presenta el modelo en un formato adecuado para
interactuar, usualmente la interfaz de usuario.
    \item Controlador: Este responde a eventos, usualmente acciones del usuario
e invoca cambios en el modelo y probablemente en la vista.
\end{itemize}

\subsection{{\em Modelo}: base de datos con SQLObject}
\subsubsection{Conexi'on de la base de datos}
La parte del modelo la desarrollamos con una base de datos MySQL
\footnote{MySQL es un sistema de gesti'on de base de datos relacional, multihilo
y multiusuario con m'as de seis millones de instalaciones.}
ya que el hosting que vamos a
adquirir nos brinda este servicio y no SQLite \footnote{es un sistema de
gesti'on de bases de datos relacional compatible con ACID, y que est'a contenida
en una relativamente peque~na librer'ia en C.} por ejemplo.

En la base de datos guardaremos toda la informaci'on que necesitemos manejar y
mostrar en nuestra p'agina. Para esto necesitamos editar el archivo {\em
dev.cfg} y buscar la l'inea que dice:

\begin{verbatim}
# sqlobject.dburi="postgres://username@hostname/databasename"
# sqlobject.dburi="mysql://username:password@hostname:port/databasename"
# sqlobject.dburi="sqlite:///file_name_and_path"
\end{verbatim}

La l'inea del medio es la que tenemos que modificar si es que queremos utilizar
MySQL como es en nuestro caso. Primero descomentamos la l'inea y ponemos el
{\em username, password, hostname, port, databasename} para que funcione todo
correctamente. Dejando todo esto entre comillas dobles, como est'a
actualmente. Debemos tener los permisos suficientes para poder utilizar esta
base de datos como usuario. En mi caso, la l'inea me qued'o as'i:
\begin{verbatim}
sqlobject.dburi="mysql://manuel@localhost:3306/wwwpayaso"
\end{verbatim}

Seguido de esto debemos comentar la l'inea que se muestra a continuaci'on ya
que por defecto TurboGears est'a configurado para utilizar SQLite.

\begin{verbatim}
sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite"
\end{verbatim}

\subsubsection{Creaci'on de la base de datos}
Ahora pasemos a crear las tablas correspondientes a la informaci'on que
necesitamos guardar en la base de datos. Para esto vamos al archivo antes
mencionado {\em model.py} y creamos una nueva clase que hereda de {\em
SQLObject}; veamos c'omo queda nuestro c'odigo:

\begin{verbatim}
class Photo(SQLObject):
    names = UnicodeCol(default="")
    #hour = TimeCol(notNone=True)
    disco = ForeignKey("Disco")
    date = ForeignKey("Date")
    image = UnicodeCol(notNone=True, unique=True)
    thumbail = UnicodeCol(notNone=True, unique=True)
\end{verbatim}

\begin{description}
    \item [Photo] nombre de la tabla SQL.
    \item [names] lista de nombres de las personas que aparecen en la foto.
    \item [disco] relaci'on a una instancia de la clase Disco que contiene
informaci'on sobre la discoteca de la foto.
    \item [date] relaci'on a una instancia de la clase Date que contiene la
fecha en la cu'al fu'e tomada la fotograf'ia.
    \item [image] direcci'on relativa en la que se encuentra la imagen en
tama~no real.
    \item [thumbail] direcci'on relativa en la que se encuentra la imagen en
tama~no peque~no.
\end{description}

\begin{verbatim}
class Disco(SQLObject):
    name = UnicodeCol(notNone=True, unique=True)
    address = UnicodeCol(default="")
    telephone = UnicodeCol(default="")
    http = UnicodeCol(default="")
    description = UnicodeCol(default="")
    logo = UnicodeCol(default="")
\end{verbatim}

\begin{description}
    \item [Disco] nombre de la tabla SQL.
    \item [name] nombre de la discoteca, bar, pub, etc en la cual fu'e tomada
la fotograf'ia.
    \item [address] direcci'on f'isica de la discoteca.
    \item [telephone] tel'efono de la discoteca.
    \item [http] direcci'on de alguna p'agina web que la disco posea.
    \item [description] alg'un texto descriptivo sobre esta.
    \item [logo] direcci'on relativa en la que se encuentra la imagen de su lo
go en tama~no real.
\end{description}

\begin{verbatim}
class Date(SQLObject):
    date = DateCol(notNone=True, unique=True)
    #hour = TimeCol(notNone=True)
\end{verbatim}

\begin{description}
    \item [Date] nombre de la tabla SQL.
    \item [date] fecha en formato del m'odulo {\em datetime} (datetime.date).
\end{description}

\begin{verbatim}
class News(SQLObject):
    date = ForeignKey("Date")
    disco = ForeignKey("Disco")
    short_description = UnicodeCol(notNone=True)
    long_description = UnicodeCol(notNone=True)
    title = UnicodeCol(notNone=True)
\end{verbatim}

\begin{description}
    \item [Date] nombre de la tabla SQL.
    \item [date] relaci'on a una instancia de la clase Date que contiene la
fecha de la noticia.
    \item [disco] relaci'on a una instancia de la clase Disco que contiene
informaci'on sobre la discoteca de la noticia.
    \item [short\_description] alg'un texto corto de descripci'on sobre la
noticia.
    \item [long\_description] alg'un texto largo que describa en profundidad
noticia.
    \item [title] t'itulo de la noticia.
\end{description}

{\em Nota}: las direcciones de las im'agenes son relativas, comenzando desde la
direcci'on en la que se encuentra el proyecto; en nuesto caso se ubicar'ian en:
{\em ./wwwpayaso/static/images/photos/}

Ahora debemos crear estas tablas para poder comenzar a utilizarlas. Esto lo
hacemos con el siguiente comando desde una consola:

\begin{verbatim}
[manuel] [~/wwwpayaso]$ tg-admin sql create
Using database URI mysql://manuel@localhost:3306/wwwpayaso
[manuel] [~/wwwpayaso]$
\end{verbatim}

% CONTINUAR DESDE ACA

\subsubsection{Manejo de la base de datos}
Para agregar una foto a la base de datos basta con iniciar un int'erprete python
con el comando {\em tg-admin} de TurboGears para que cargue autom'aticamente
todos los m'odulos necesarios, en otras palabras, carga todo nuestro proyecto.
El comando es el siguiente:

\begin{verbatim}
[manuel] [~/wwwpayaso]$ tg-admin shell
Python 2.5.1 (r251:54863, May  2 2007, 16:27:44)
Type ''copyright'', ''credits'' or ''license'' for more information.

IPython 0.7.3 -- An enhanced Interactive Python.
?       -> Introduction to IPython's features.
%magic  -> Information about IPython's 'magic' % functions.
help    -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.

In [1]: import datetime

In [2]:
Photo(disco=''baucis'',date=datetime.date.today(),
image=''static/images/someimage.jpg'',
thumbail=''static/images/thumbail/somethumbail.jpg'')
Out[2]: <Photo 26 disco=u'baucis' date='datetime.date(200...)'
image=''u'static/images/s...''' thumbail=''u'static/images/t...'''>

In [3]: Photo.get(1)
Out[3]: <Photo 26 disco=u'baucis' date='datetime.date(200...)'
image=''u'static/images/s...''' thumbail=''u'static/images/t...'''>
\end{verbatim}

Esto quiere decir que ingresamos una foto a la tabla {\em Photo} con los datos
que le pasamos por argumento {\em In [2]: Photo(...)} y luego adquirimos la foto
que acabamos de ingresar {\em In [3]: Photo.get(1)}.

La administraci'on de la base de datos la podemos hacer tambi'en a trav'es de
una interfaz web bast'ante amigable. Esta forma nos permite crear las tablas
necesarias y mientras ir viendo un diagrama de c'omo estar'ian relacionadas
entre s'i. Para realizar la creaci'on y modificaci'on de la base de datos
tipeamos en una consola:

\begin{verbatim}
[manuel] [~/www-payaso]$ tg-admin toolbox
\end{verbatim}

Lo que nos abre una pesata~na en el navegador, si es que lo tenemos abierto, o
directamente abre un nuevo navegador en la direcci'on {\em
http://localhost:7654/}, lo que se tiene que ver similar a la Figura
~\ref{fig:toolbox}. En esta p'agina podemos acceder a la secci'on {\em
ModelDesigner} para crear/dise~nar la base de datos o, si ya la hemos creado
anteriormente en el archivo {\em model.py}, vamos directamente a {\em CatWalk}.
Siguiendo lo que se muestra dentro de estas secciones es muy f'acil crear o
modificar todo lo necesario. Las otras secciones las explicaremos m'as adelante
en el cap'itulo.

\begin{figure}[ht]
\centering
\includegraphics[scale=0.25]{images/fig-02.eps}
\caption{{\small TurboGears Toolbox}}
\label{fig:toolbox}
\end{figure}

\subsection{{\em Vista}: XHTML, CSS y dem'as}
\subsubsection{Introducci'on}
Las p'aginas webs que utiliza TurboGears son construidas mediantes el lenguaje
{\em XHTML} \footnote{XHTML, acr'onimo ingl'es de eXtensible Hypertext Markup
Language (lenguaje extensible de marcado de hipertexto), es el lenguaje de
marcado pensado para sustituir a HTML como est'andar para las p'aginas web.} el
cual permite ''dise~nar'' lo que se mostrar'a en pantalla cuando el usuario
ingrese la direcci'on de esta en su navegador. Lo que se prentende aqu'i es
simplemente plasmar el {\em contenido} de la web y no el dise~no en lo que se
refiere a tipograf'ia y colores. Para esto se utilizar {\em CSS}
\footnote{son un lenguaje formal usado para definir la presentaci'on de un
documento estructurado escrito en HTML o XML (y por extensi'on en XHTML).} el
cu'al permite con simples atributos definir todo lo referido a colores,
ubicaci'on de texto, fondo, im'agenes, etc. Todas los {\em templates} se guardan
en la carpeta {\em ./wwwpayaso/templates/}, en la cual ya hay algunos por
defecto que son autom'aticamente generados cuando creamos el proyecto.

\begin{description}
    \item [master.kid] este template es cargado siempre que llamemos a cualquier
p'agina. En 'el se encuentra la infomaci'on acerca del encabezado (header) y
piecera (footer), por lo que una funci'on que llame a cualquier otro template lo
'unico que se modificar'a es el cuerpo de este, manteniendo el mismo {\em
header} y {\em footer} para todos.

    \item [welcome.kid] se crea a modo de ejemplo as'i cuando cargamos la
primer p'agina vemos algo bonito y nos damos cuenta de que est'a funcionando
correctamente.

    \item [login.kid] none.
\end{description}

\subsubsection{Utilizaci'on de CSS}
Como ya hemos visto CSS permite separar el contenido del dise~no en cuanto a
colores, tipograf'ia y dem'as. Utilizamos esto por una cuesti'on de comodidad y
legibilidad en el c'odigo de los templates. Si bien muchas, o quiz'as todas las
cosas que utilizemos de CSS, se pueda hacer con XHTML, esto no es
recomendable.

Estos atributos (alineaci'on, color, etc) con sus respectivos valores
(justificado, rojo, etc) se guardan en archivos con extenci'on {\em .css}, los
cuales hemos establecidos en las convenciones d'onde ser'an ubicados. Para
hacer todav'ia m'as f'acil la implementaci'on de nuestra p'agina, la
dividiremos en {\em frames} para 'unicamente actualizar o modificar s'olo
partes de la p'agina (lo que va a ir cambiando a medida que vayamos navegando) y
no toda entera. En las referencias se pueden encontrar un manual de CSS.

\subsection{{\em Controlador}: CherryPy}
\subsubsection{Introducci'on}
'Esta es una de las secciones m'as importantes ya que, no s'olo, mostraremos
realmente c'omo funciona nuestro proyecto, sino tambi'en explicaremos en
detalle cada una de las expresiones y funciones que se vayan necesitando a
medida que avancemos en el mismo.

CherryPy es el controlador de nuestro proyecto, es el v'inculo entre la vista y
el ''motor'' que se encuentra detr'as de la p'agina a simple vista. Cuando
nosotros colocamos la direcci'on de la p'agina en nuestro navegador este
consulta y dialoga con CherryPy el cu'al ejecuta c'odigo Python y devuelve las
respuestas nuevamente a la vista. Podemos ver 'esto de forma gr'afica en la
Figura ~\ref{fig:mvc}, d'onde se muestra la conexi'on entre cada uno de los
m'odulos que hemos ido explicando. En pocas palablas, y resumiendo lo explicado
en las secciones anteriores, cada uno de estos m'odulos se encarga de:

\begin{description}
    \item [Mochikit] es una librer'ia limpia y potente de {\em JavaScript}.
    \item [Kid] es un dise~nador y amigable programador de los sistemas
de templates.
    \item [CherryPy] hace posible la entrada y salida de nuestra web, de manera
tan f'acil como es escribir una funci'on en Python.
\end{description}

\begin{figure}[ht]
\centering
\includegraphics[scale=0.9]{images/fig-03.eps}
\caption{{\small Modelo-Vista-Controlador}}
\label{fig:mvc}
\end{figure}

\subsubsection{Primer funci'on}
Al crear el proyecto, este crea los archivos que explicamos anteriormente. En
esta secci'on nos vamos a focalizar en {\em controllers.py}. Ya que es aqu'i
d'onde va todo el c'odigo Python para que nuestra web funcione correctamente.
Vamos a ver qu'e es lo que contiene este archivo al momento de ser creado.

\begin{verbatim}
from turbogears import controllers, expose, flash
# from model import *
# import logging
# log = logging.getLogger(''wwwpayaso.controllers'')

class Root(controllers.RootController):
    @expose(template=''wwwpayaso.templates.welcome'')
    def index(self):
        import time
        # log.debug(''Happy TurboGears Controller Responding For Duty'')
        flash(''Your application is now running'')
        return dict(now=time.ctime())
\end{verbatim}

En las primeras l'ineas importamos los m'odulos necsarios. Luego vemos una
definici'on de una clase que hereda de {\em controllers.RootController}. 'Esta
es la clase que se encarga de interpretar todas las direcciones que ingresemos
en la {\em barra de direcciones} de nuestro navegador.

Esta clase por defecto viene con la funci'on {\em index} definida; 'esta es la
que se llama cuando accedemos al {\em home} de nuestra web. En este caso cuando
pongamos la direcci'on {\em http://localhost:8080} la estar'iamos llamando.

Notemos que antes de la definici'on de la funci'on y despu'es de la
definici'on de la clase, vemos un decorador, {\em
@expose(template=''wwwpayaso.templates.welcome'')}, esto significa que est'amos
conectando esa funci'on con el template {\em welcome.kid} para que cuando
llamemos a esta funci'on lo que retorne sea pasado a esa p'agina y poder
realizar lo que queramos con el resultado. Podemos ver en detalle los
decoradores en los links de referecias.

La funci'on {\em index} retorna un diccionario de la forma \{now: ''17-08-07
11:04:25''\}, esta informaci'on es utilizada en el template para mostrarla en la
p'agina. Todas las funciones en TurboGears deben retornar un {\em string,
diccionario o generador}; de otra forma el servidor web nos informar'a de dicho
error.

\subsubsection{Funciones para la base de datos}
A medida que vayamos desarrollado las funciones relacionadas con la base
de datos ser'an escritas en esta secci'on, sujetas a cualquier modificaci'on
que se presente a lo largo de la creaci'on del proyecto. Hasta el momento se
pueden describir las siguientes:

\begin{description}
    \item [update\_database(self)] se encarga de actualizar la base de datos,
lo que significa que agregar'a las direcciones de las fotos que a'un no se
hallan cargado. Para esto recorre la direcci'on {\em
./wwwpayaso/static/images/photos} mediante la funci'on {\em os.walk()}, con el
criterio de parada cuando llegamos al directorio que contiene la carpeta {\em
thumbails}. Este funciona preguntando para cada disco que encuentra en el
directorio si esta ya existe o no, de no existir la inserta; hace lo mismo para
las fechas y las fotos. La verificaci'on se hace
por medio del manejo de la excepci'on {\em DuplicateEntryError} de SQLObject.
Retorna 'unicamente un {\em string} informativo de que la base de datos fu'e
actualizada correctamente.
    \item [show\_photos(self)] hace una consulta pidiento todas las fotos que
tengamos cargadas. Luego el paginador de TurboGears {\em @paginate}
\footnote{http://docs.turbogears.org/1.0/PaginateDecorator} se encarga de
dividir en p'aginas nuestra consulta retornando este n'umero de items (por
defecto se divide a 10). Parece complicado pero es s'olo una cuesti'on de
comprender como funciona el {\em @paginate}.
\end{description}